package com.compass.tumor


import android.app.Activity
import android.app.Application
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import androidx.multidex.MultiDex
import com.compass.doctor.ui.MainActivity
import com.compass.doctor.ui.patient.VideoAnswerActivity
import com.compass.framework.constant.CANCEL_INVITE
import com.compass.framework.constant.CLOSE_EVENT
import com.compass.framework.constant.NIM_APP_KEY
import com.compass.framework.constant.REFRESH_MESSAGE
import com.compass.framework.ext.toJson
import com.compass.framework.helper.CompassAppHelper
import com.compass.framework.manager.ActivityManager
import com.compass.framework.manager.AppFrontBack
import com.compass.framework.manager.AppFrontBackListener
import com.compass.framework.manager.AppManager
import com.compass.framework.manager.CommonManager
import com.compass.framework.manager.UserInfoManager
import com.compass.framework.toast.TipsToast
import com.compass.framework.update.util.NotificationUtil
import com.compass.framework.utils.LiveDataBus
import com.compass.framework.utils.LogUtil

import com.compass.tumor.push.PushMessageHandler
import com.compass.tumor.splash.SplashActivity
import com.heytap.msp.push.HeytapPushManager
import com.hihonor.push.sdk.HonorPushClient
import com.huawei.hms.support.common.ActivityMgr
import com.netease.nimlib.sdk.NIMClient
import com.netease.nimlib.sdk.Observer
import com.netease.nimlib.sdk.auth.LoginInfo
import com.netease.nimlib.sdk.avsignalling.SignallingServiceObserver
import com.netease.nimlib.sdk.avsignalling.constant.SignallingEventType
import com.netease.nimlib.sdk.avsignalling.event.CanceledInviteEvent
import com.netease.nimlib.sdk.avsignalling.event.ChannelCloseEvent
import com.netease.nimlib.sdk.avsignalling.event.ChannelCommonEvent
import com.netease.nimlib.sdk.avsignalling.event.ControlEvent
import com.netease.nimlib.sdk.avsignalling.event.InviteAckEvent
import com.netease.nimlib.sdk.avsignalling.event.InvitedEvent
import com.netease.nimlib.sdk.avsignalling.event.UserJoinEvent
import com.netease.nimlib.sdk.avsignalling.event.UserLeaveEvent
import com.netease.nimlib.sdk.msg.MsgServiceObserve
import com.netease.yunxin.kit.corekit.im.IMKitClient
import com.netease.yunxin.kit.corekit.im.repo.SettingRepo
import com.netease.yunxin.kit.corekit.im.utils.IMKitUtils
import com.netease.yunxin.kit.locationkit.LocationKitClient
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.ClassicsHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.tencent.mmkv.MMKV
import com.tencent.mmkv.MMKVLogLevel
import com.vivo.push.PushClient
import com.vivo.push.util.VivoPushException


/**
 * 应用类
 */
class CompassApplication : Application() {

    companion object {
        private const val TAG = "CompassApplication==="
        private var coldStart = false
        private var isFront = false//是否是前台

        @JvmStatic
        var foregroundActCount = 0
            private set // //setter方法私有，仅在 CompassApplication.kt 文件中可见

        @JvmStatic
        fun setColdStart(value: Boolean) {
            coldStart = value
        }
    }


    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MultiDex.install(base)
    }

    override fun onCreate() {
        super.onCreate()
        CompassAppHelper.init(this, BuildConfig.DEBUG)
        AppManager.init(this)
        initMVVK()
        //注册APP前后台切换监听
        appFrontBackRegister()
        // App启动立即注册监听
        registerActivityLifecycle()
        TipsToast.init(this)
        initUIKit()
        initRefreshHead()


    }

    private fun initMVVK() {
        MMKV.initialize(this)
        MMKV.setLogLevel(
            if (BuildConfig.DEBUG) {
                MMKVLogLevel.LevelDebug
            } else {
                MMKVLogLevel.LevelError
            }
        )
    }


    private fun initRefreshHead() {
        //设置全局的Header构建器
        SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
//            CustomRefreshHeader(context)
            ClassicsHeader(context)
        }
        //设置全局的Footer构建器
        SmartRefreshLayout.setDefaultRefreshFooterCreator { context, layout ->
            //指定为经典Footer，默认是 BallPulseFooter
            ClassicsFooter(context)
        }
    }

    /**
     * 初始化IM_SDK
     */
    private fun initUIKit() {
        val options = NimSDKOptionConfig.getSDKOptions(this, NIM_APP_KEY)
        val loginInfo =
            LoginInfo(UserInfoManager.getImUserAccount(), UserInfoManager.getImUserToken())

        if (CommonManager.getPrivacyStatus()) {
            //如果用户同意后，直接对sdk初始化
            LogUtil.d(TAG + "直接对sdk初始化")

            IMKitClient.init(this, loginInfo, options)
            initPushSDK()

        } else {
            //如果用户未同意，先调用config
            LogUtil.d(TAG + "先调用config对sdk初始化")
            IMKitClient.config(this, loginInfo, options);
        }

    }

    private fun initPushSDK() {
        if (IMKitUtils.isMainProcess(this)) {
            // 位置消息模块需要初始化
            LocationKitClient.init(this)
            //huawei push
            ActivityMgr.INST.init(this)
            //honor push
            HonorPushClient.getInstance().init(this, true)

            //oppo push
            HeytapPushManager.init(this, true)
            try {
                //vivo push
                PushClient.getInstance(this).initialize()
            } catch (e: VivoPushException) {
                e.printStackTrace()
            }
            IMKitClient.toggleNotification(SettingRepo.isPushNotify())
            initCustomNotification()
        }
        IMKitClient.registerMixPushMessageHandler(PushMessageHandler())

    }

    private var onlineObserver = Observer<ChannelCommonEvent> { event: ChannelCommonEvent? ->

        when (event?.eventType) {
            SignallingEventType.CLOSE -> {
                var channelCloseEvent = event as ChannelCloseEvent

                LiveDataBus.get().with(CLOSE_EVENT).postValue(channelCloseEvent.channelBaseInfo)
                LogUtil.d(
                    "频道关闭事件 channelCloseEvent==${channelCloseEvent.toJson()}",
                    tag = TAG
                )
            }

            SignallingEventType.UN_KNOW -> {
                LogUtil.d("未知事件", tag = TAG)
            }

            SignallingEventType.JOIN -> {
                var userJoinEvent = event as UserJoinEvent

                LogUtil.d(
                    "有人加入频道事件 userJoinEvent==${userJoinEvent.toJson()}",
                    tag = TAG
                )
            }

            SignallingEventType.INVITE -> {
                var inviteEvent = event as InvitedEvent
                val intent = Intent(applicationContext, VideoAnswerActivity::class.java)
                intent.putExtra("invitedEvent", inviteEvent)
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                if (isFront){
                    startActivity(intent)
                }else{
                    // 创建一个 PendingIntent，当点击通知时执行
                    val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        PendingIntent.getActivity(this, 123, intent, PendingIntent.FLAG_IMMUTABLE)
                    } else {
                        PendingIntent.getActivity(this, 123, intent,
                            PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_MUTABLE)
                    }



                    NotificationUtil.showImVideoNotification(
                        this, com.compass.doctor.R.drawable.ic_notification_logo,
                        "温馨提示",
                        "您收到了一个视频邀请，点击查看", pendingIntent
                    )

                    startActivity(intent)
                }
                //收到邀请
                LogUtil.d("被邀请事件  inviteEvent==${inviteEvent.toJson()}", tag = TAG)

            }

            SignallingEventType.CANCEL_INVITE -> {
                var canceledInviteEvent = event as CanceledInviteEvent
                LiveDataBus.get().with(CANCEL_INVITE).postValue(canceledInviteEvent.channelBaseInfo)
                LogUtil.d(
                    "取消邀请事件 canceledInviteEvent==${canceledInviteEvent.toJson()}",
                    tag = TAG
                )
            }

            SignallingEventType.REJECT, SignallingEventType.ACCEPT -> {
                var inviteAckEvent = event as InviteAckEvent


                LogUtil.d(
                    "对方拒绝/接受 邀请事件 inviteAckEvent===${inviteAckEvent.toJson()}",
                    tag = TAG
                )
            }

            SignallingEventType.LEAVE -> {
                var userLeaveEvent = event as UserLeaveEvent
                LogUtil.d(
                    "有用户离开频道事件  userLeaveEvent==${userLeaveEvent.toJson()}",
                    tag = TAG
                )
            }

            SignallingEventType.CONTROL -> {
                var controlEvent = event as ControlEvent
                LogUtil.d(
                    "自定义控制命令事件  controlEvent==${controlEvent.toJson()}",
                    tag = TAG
                )
            }

            else -> {
                LogUtil.d("未知事件", tag = TAG)
            }
        }

    }

    // 离线事件观察者
    private val offlineObserver = Observer<ArrayList<ChannelCommonEvent>> { list ->
        for (event in list) {
            val eventType = event.eventType
            when (eventType) {
                SignallingEventType.CLOSE -> {
                    var channelCloseEvent = event as ChannelCloseEvent
                    LogUtil.d(
                        "频道关闭事件 offlineObserver==${channelCloseEvent.toJson()}",
                        tag = TAG
                    )
                }

                SignallingEventType.JOIN -> {
                    var userJoinEvent = event as UserJoinEvent
                    LogUtil.d(
                        "有人加入频道事件 offlineObserver==${userJoinEvent.toJson()}",
                        tag = TAG
                    )
                }

                SignallingEventType.INVITE -> {
                    var invitedEvent = event as InvitedEvent
                    LogUtil.d("被邀请事件  offlineObserver==${invitedEvent.toJson()}", tag = TAG)
                }

                SignallingEventType.CANCEL_INVITE -> {
                    var canceledInviteEvent = event as CanceledInviteEvent
                    LogUtil.d(
                        "取消邀请事件 offlineObserver==${canceledInviteEvent.toJson()}",
                        tag = TAG
                    )
                }

                SignallingEventType.REJECT, SignallingEventType.ACCEPT -> {
                    var ackEvent = event as InviteAckEvent
                    LogUtil.d(
                        "对方拒绝/接受 邀请事件 offlineObserver===${ackEvent.toJson()}",
                        tag = TAG
                    )
                }

                SignallingEventType.LEAVE -> {
                    var userLeaveEvent = event as UserLeaveEvent
                    LogUtil.d(
                        "有用户离开频道事件  offlineObserver==${userLeaveEvent.toJson()}",
                        tag = TAG
                    )
                }

                SignallingEventType.UN_KNOW -> {

                }

                SignallingEventType.CONTROL -> {
                    var controlEvent = event as ControlEvent
                    LogUtil.d(
                        "自定义控制命令事件  offlineObserver==${controlEvent.toJson()}",
                        tag = TAG
                    )
                }
            }
        }
    }

    /**
     * 注册云信自定义通知
     */
    private fun initCustomNotification() {
        NIMClient.getService(MsgServiceObserve::class.java).observeCustomNotification({
            LiveDataBus.get().with(REFRESH_MESSAGE).postValue(REFRESH_MESSAGE)
            LogUtil.e("自定义通知==${it.toJson()}")
            it.apnsText?.let { text ->
                val intent = Intent(this, MainActivity::class.java)
                // 创建一个 PendingIntent，当点击通知时执行
                var pendingIntent = PendingIntent.getActivity(
                    this, 0, intent,
                    PendingIntent.FLAG_IMMUTABLE
                )
                NotificationUtil.showImNotification(
                    this, com.compass.doctor.R.drawable.ic_notification_logo,
                    "温馨提示",
                    text, pendingIntent
                )
            }
        }, true)


        // 在线通知事件观察者

        NIMClient.getService(SignallingServiceObserver::class.java)
            .observeOnlineNotification(onlineObserver, true)


//        // 注册离线事件观察者
//        NIMClient.getService(SignallingServiceObserver::class.java)
//            .observeOfflineNotification(offlineObserver, true)
    }



    /**
     * 注册APP前后台切换监听
     */
    private fun appFrontBackRegister() {
        AppFrontBack.register(this, object : AppFrontBackListener {
            override fun onBack(activity: Activity?) {
                LogUtil.d("onBack", tag = TAG)
                isFront=false
            }

            override fun onFront(activity: Activity?) {
                LogUtil.d("onFront", tag = TAG)
                isFront=true
            }
        })
    }

    /**
     * 注册Activity生命周期监听
     * 用于系统杀死应用之后，系统恢复应用，可能存在没有登录的异常
     * 此处如果在没有登录的情况下，其他页面打开的时候进行finish();除了MainActivity
     *  MainActivity启动进行登录检测，如果没有登录进行登录操作
     */
    private fun registerActivityLifecycle() {
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityPaused(activity: Activity) {
            }

            override fun onActivityStarted(activity: Activity) {
                foregroundActCount++
            }

            override fun onActivityDestroyed(activity: Activity) {
                ActivityManager.pop(activity)
            }

            override fun onActivitySaveInstanceState(activity: Activity, p1: Bundle) {
            }

            override fun onActivityStopped(activity: Activity) {
                foregroundActCount--
            }

            override fun onActivityCreated(activity: Activity, p1: Bundle?) {
                if (TextUtils.isEmpty(IMKitClient.account()) && !(activity is MainActivity || activity is SplashActivity) && !coldStart) {
                    activity.finish()
                } else {
                    ActivityManager.push(activity)
                }

            }

            override fun onActivityResumed(activity: Activity) {
            }
        })
    }

    override fun onTerminate() {
        super.onTerminate()
        foregroundActCount = 0
    }

}